/* eslint-disable @typescript-eslint/no-explicit-any */
import { isNil } from "ramda";
import { onBeforeUnmount, Ref, watch } from "vue";
import { listenJSEvent, NOOP } from "@ibiz-template/core";

/**
 * 监听JS原生事件，返回cleanup回调，调用后删除该监听
 *
 * @export
 * @param {Ref} elRef
 * @param {string} eventName
 * @param {(..._args: any[]) => any} listener
 * @param {AddEventListenerOptions} [options={}]
 * @return {*}  {() => void}
 */
export function useEventListener(
  elRef: Ref,
  eventName: string,
  listener: (..._args: any[]) => any,
  options: AddEventListenerOptions = {}
): () => void {
  let cleanup = NOOP;

  watch(
    elRef,
    (newVal, oldVal) => {
      if (newVal !== oldVal) {
        if (isNil(newVal)) {
          cleanup();
          cleanup = NOOP;
        } else {
          cleanup = listenJSEvent(
            newVal?.$el || newVal,
            eventName,
            listener,
            options
          );
        }
      }
    },
    { immediate: true }
  );

  // 组件销毁前销毁监听
  onBeforeUnmount(() => {
    if (cleanup !== NOOP) {
      cleanup();
    }
  });

  return () => {
    cleanup();
  };
}
